<template>
  <div class="editor-container" ref="messageArea">
    <template v-if="editId">
      <!-- 工具栏 -->
      <div class="toolbar">
        <Toolbar
          :editor="editorRef"
          :defaultConfig="toolbarConfig"
          mode="default"
        />
        <div class="tip">
          <div class="tip-text">按下tab接受输出，按下ESC不接受输出</div>
          <div
            class="ai-suggestion-btn"
            @click="handleOpenModels('continue_write')"
          >
            <img src="" alt="" />
            <svg-icon className="write" iconClass="write"></svg-icon>
            <span class="text"
              >{{ !autoform.isStartAuto ? "开启续写" : "停止续写" }}
            </span>
          </div>
        </div>
      </div>

      <div class="editorTitle">
        <el-input v-model="title" placeholder="请输入标题"></el-input>
        <span class="total">本章已创作字数：{{ currentLength }} / 10000</span>
      </div>
      <!-- 编辑器 -->
      <Editor
        class="editor"
        v-model="editorContent"
        :defaultConfig="editorConfig"
        mode="default"
        @onCreated="handleCreated"
        @onChange="handleSelectionChange"
      />
      <!--扩写-->
      <div class="autoWriteContent" v-show="autoform.autoContent">
        <div class="autoWrite" :class="autoform.tooltype">
          <i class="el-icon-loading" v-show="autoform.autoLoading"></i>
          <span v-html="autoform.autoContent"></span>
        </div>
      </div>
    </template>
    <div v-else class="noDate">
      <img src="@/assets/images/zzzw.png" alt="" />
      无选中的章节内容展示
    </div>
    <!-- 自定义悬浮菜单 -->
    <div
      v-show="showOperationBox"
      :style="operationBoxStyle"
      class="operation-box"
    >
      <!-- <div><img src="@/assets/images/icon_xx.png" />续写</div> -->
      <div @click.stop.prevent="handleOpenModels('polish_text')">
        <img src="@/assets/images/icon_rs.png" />
        <img class="imgText" src="#" alt="润色" />
        <span>润色</span>
      </div>
      <!-- <div><img src="@/assets/images/icon_kz.png" />扩展</div> -->
      <div @click.stop.prevent="handleOpenModels('expand_text')">
        <img src="@/assets/images/icon_kx.png" />
        <img class="imgText" src="" alt="扩写" />
        <span>扩写</span>
      </div>
      <div @click.stop.prevent="handleOpenModels('refine_text')">
        <img src="@/assets/images/icon_gx.png" />
        <img class="imgText" src="" alt="细化" />
        <span>细化</span>
      </div>
    </div>
    <SelectModelsDialog
      @close="showModel = false"
      :visible.sync="showModel"
      @confirm="handleSelectModel"
      v-if="showModel"
    ></SelectModelsDialog>
  </div>
</template>

<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import SelectModelsDialog from "./SelectModelsDialog.vue";
import {
  conversationAiWrite,
  conversationAiWrite2,
  conversationAiStop,
} from "@/api/conversation";
import { getToken } from "@/utils/auth";
let timer = null;
export default {
  components: { Editor, Toolbar, SelectModelsDialog },
  props: {
    editId: {},
    currentType: {
      type: String,
      default: () => "",
    },
    // dataObj 包含 { title, content }
    dataObj: {
      type: Object,
      default: () => ({ title: "", content: "", description: "" }),
    },
  },
  data() {
    return {
      showModel: false,
      currentLength: 0,
      title: "",
      editorRef: null, // 编辑器实例
      editorContent: "", // 编辑器内容
      toolbarConfig: {
        toolbarKeys: [
          "undo", // 撤销
          "redo", // 重做
          "headerSelect", // 标题
          "|",
          "fontFamily", // 字体
          "bold", // 加粗
          "blockquote", // 引用
          "italic", // 斜体
          "underline", // 下划线
          "through", // 删除线
          "color", // 文字颜色
          "numberedList", // 有序列表
          "bulletedList", // 无序列表
          {
            key: "group-justify",
            title: "对齐",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
            menuKeys: [
              "justifyLeft",
              "justifyRight",
              "justifyCenter",
              "justifyJustify",
            ],
          },
        ],
      }, // 工具栏配置
      editorConfig: {
        placeholder: "请输入正文",
        hoverbarKeys: { text: {} }, // 隐藏默认悬浮菜单
      },
      showOperationBox: false, // 是否显示自定义悬浮菜单
      operationBoxStyle: {
        position: "absolute",
        top: "0",
        left: "0",
      },
      autoform: {
        //自动补全内容
        autoContent: "",
        tooltype: "continue_write", //默认续写类型
        model: "",
        pattern: 1,
        isStartAuto: false,
        autoLoading: false,
      },
    };
  },
  watch: {
    editorContent: {
      immediate: false,
      handler(newVal) {
        const length = this.editorRef.getText().length;
        this.currentLength = length;
        if (length > 10000) {
          this.$message.warning("字数不能超过10000字");
          this.editorContent = this.editorContent.substring(0, 10000);

          return;
        }
        if (this.autoform.isStartAuto) {
          this.handleCallBack(() => {
            this.handleAIWrite();
          }, 500);
        }
      },
    },
    dataObj: {
      deep: true,
      immediate: false,
      handler() {
        this.initEditorContent();
      },
    },
  },
  methods: {
    //打开模型
    handleOpenModels(toolType) {
      if (toolType == "continue_write" && this.autoform.isStartAuto) {
        return this.handleAISuggestion();
      }
      this.autoform.tooltype = toolType;
      this.showModel = true;
    },
    //选择模型
    handleSelectModel(model_name, type) {
      this.autoform.pattern = type;
      this.autoform.model = model_name;
      if (this.autoform.toolType == "continue_write") {
        this.handleAISuggestion();
      } else {
        this.handleAIWrite(this.autoform.tooltype);
      }
    },
    //滚动到最底部
    scrollToBottom() {
      this.$nextTick(() => {
        const messageArea = this.$refs.messageArea;
        messageArea.scrollTop = messageArea.scrollHeight;
      });
    },
    //流式接口处理回调
    async handleStreamResponse(response) {
      const reader = response.body.getReader();
      const decoder = new TextDecoder("utf-8");
      let buffer = "";
      let params = { role: "ai", content: "", id: "", conversation_id: "" };
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        //关掉自动加载的话就终止
        if (!this.autoform.autoLoading) {
          this.autoform.autoContent = "";
          this.autoform.autoLoading = false;
          break;
        }
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split("\n \n");
        for (const line of lines) {
          if (line.indexOf("data: ") > -1) {
            const data = line.replace("data: ", "");
            if (data.indexOf("[DONE]") > -1) {
              this.autoform.autoLoading = false;
            } else {
              this.autoform.autoContent += data;
            }
            this.scrollToBottom();
          }
        }

        buffer = lines[lines.length - 1];
      }
    },
    //开始续写\润色\扩写\细写功能
    async handleAIWrite(toolType = "continue_write") {
      //有在续写进行中提示
      if (this.autoform.autoLoading) {
        this.$message.warning("请等待上一次AI编写完成");
        return;
      }
      //存在就清空
      if (this.autoform.autoContent) {
        this.autoform.autoContent = "";
      }
      const id = Number(this.$route.params.id);
      const params = {
        ai_tool_id: toolType, //续写-continue_write  ； 润色-polish_text  ; 扩写 - expand_text  ;   细化-refine_text
        creation_id: id, //作品ID
        context: this.editorContent, // 上下文
        model: this.autoform.model,
        pattern: this.autoform.pattern,
      };
      let range = window.getSelection().getRangeAt(0);
      let rangeNum = range.startOffset;
      if (rangeNum > 0) {
        // 截取光标前 1000 个字符
        const fullText = this.editorRef.getText();
        const textBeforeCursor = fullText.slice(0, rangeNum); // 获取光标前的文本
        const last1000Chars = textBeforeCursor.slice(-1000); // 截取前 1000 个字符
        params.context = last1000Chars;
      }
      //润色-扩写-细节需要加一个参数
      if (toolType != "continue_write") {
        const selection = this.editorRef.getSelectionText();
        params.goals = selection;
      }

      this.autoform.tooltype = toolType;
      this.autoform.autoLoading = true;
      try {
        const response = await fetch(
          `/prod-api/api/v1/conversation/stream_text`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Authorization: "Bearer " + getToken(),
            },
            body: JSON.stringify(params),
          }
        );
        this.handleStreamResponse(response);
      } catch (e) {
        this.autoform.autoLoading = false;
      }
    },
    //终止续写\润色\扩写\细写功能
    async handleAIStop() {
      const id = Number(this.$route.params.id);
      await conversationAiStop({
        ai_tool_id: this.autoform.toolType,
        creation_id: id,
      });
      this.autoform.autoContent = "";
      this.autoform.autoLoading = false;
    },
    //开启\关闭
    async handleAISuggestion() {
      if (!this.autoform.isStartAuto) {
        this.handleAIWrite();
      } else {
        this.handleAIStop();
      }
      this.autoform.isStartAuto = !this.autoform.isStartAuto;
    },
    //初始化
    initEditorContent() {
      const { title, content, description } = this.dataObj;
      // 将标题作为 <h1> + 正文
      this.title = title;
      if (this.currentType == 1) {
        this.editorContent = `${description}`;
      } else {
        this.editorContent = `${content}`;
      }
      setTimeout(() => {
        this.currentLength = this.editorRef.getText().length;
      }, 100);
    },
    //tab键接受输出
    handleTab() {
      if (this.autoform.autoLoading) {
        return this.$message.warning("请等待上一次AI编写完成");
      }
      if (this.autoform.autoContent) {
        const selection = this.editorRef.getSelectionText();
        const content = this.autoform.autoContent;
        if (selection) {
          this.editorRef.insertText(`${content}`);
        } else {
          this.editorRef.insertText(`\n\n${content}`);
        }
        this.autoform.autoContent = "";
      } else {
        editor.insertText("    ");
      }
    },
    // 编辑器创建时的回调
    handleCreated(editor) {
      this.editorRef = Object.seal(editor);
    },
    //防抖
    handleCallBack(cb, time = 100) {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        cb && cb();
      }, time);
    },
    // 处理编辑器内容选择事件
    handleSelectionChange() {
      // if(this.showOperationBox) return
      setTimeout(() => {
        const selection = this.editorRef.getSelectionText();
        if (!selection) {
          // 如果选择区域为空，隐藏悬浮菜单
          this.showOperationBox = false;
        } else {
          // 如果选择了内容，显示悬浮菜单
          this.showOperationBox = true;
          this.positionOperationBox();
        }
      }, 100);
    },

    // 定位悬浮菜单
    positionOperationBox() {
      const selection = window.getSelection();
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const rect = range.getBoundingClientRect();
        console.log(rect);
        this.operationBoxStyle = {
          position: "fixed",
          top: rect.top + "px", // 调整菜单位置
          left: rect.left + "px",
        };
      }
      // const selection = this.editorRef.getSelectionPosition();
      // if (!selection) return;
      // 根据选择区域的位置设置悬浮菜单的位置
    },
  },
  mounted() {
    document.addEventListener("keydown", (event) => {
      if (event.key === "Escape" || event.keyCode === 27) {
        //续写进行中的终止-调接口
        if (this.autoform.autoLoading) {
          if (this.autoform.isStartAuto) {
            this.autoform.isStartAuto = false;
          }
          this.handleAIStop();
        } else {
          //续写完成的清空-无调用接口
          if (this.autoform.autoContent) {
            this.autoform.autoContent = "";
            this.autoform.autoLoading = false;
          }
        }
      }
      if (event.keyCode === 9 || event.key === "Tab") {
        event.stopPropagation();
        event.preventDefault();
        console.log("Tab键被按下");
        this.handleTab();
      }
    });
  },
  beforeDestroy() {
    // 组件销毁时销毁编辑器
    if (this.editorRef) {
      this.editorRef.destroy();
    }
    //退出的时候，终止续写
    if (this.autoform.autoLoading) {
      this.handleAIStop();
    }
  },
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>

<style lang="scss" scoped>
.editor-container {
  position: relative;
  height: 100%;
  overflow: auto;
  .autoWriteContent {
    padding: 0 10px;
    margin-bottom: 15px;
    margin-top: -10px;
    position: relative;

    .autoWrite {
      white-space: pre-line;
      i {
        margin-right: 4px;
      }
    }

    //续写
    .continue_write {
      color: #4b559a;
    }

    //润色
    .polish_text {
      color: #8a5029;
    }

    //扩写
    .expand_text {
      color: #298a7a;
    }

    //细化
    .refine_text {
      color: #87298a;
    }
  }

  .noDate {
    text-align: center;
    padding-top: 350px;
    font-size: 14px;
    color: rgba(0, 1, 27, 0.3);

    img {
      width: 140px;
      display: block;
      margin: 0 auto;
    }
  }

  .toolbar {
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 44px;
    position: sticky;
    top: 0;
    z-index: 11;
    background: #fff;
    .tip {
      display: flex;
      align-items: center;
      .tip-text {
        color: rgba(0, 1, 27, 0.5);
        font-family: "PingFang SC";
        font-size: 12px;
        font-style: normal;
        font-weight: 400;
        line-height: normal;
        margin-right: 24px;
      }
    }
    .ai-suggestion-btn {
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #165deb;
      border-radius: 6px;
      width: 88px;
      height: 30px;
      margin-right: 24px;
      position: relative;
      img {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        opacity: 0;
      }
      .text {
        color: #fff;
        font-weight: 500;
        font-size: 12px;
        color: #ffffff;
      }

      .write {
        margin-right: 4px;
      }
    }
  }

  .operation-box {
    position: fixed;
    background: #fff;
    box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.2);
    border-radius: 8px 8px 8px 8px;
    border: 1px solid rgba(0, 0, 0, 0.06);
    display: flex;
    justify-content: space-around;
    align-items: center;
    z-index: 99;
    transition: opacity 0.3s ease;
    padding: 10px 24px;
    transform: translateY(-50px);
    .imgText {
      opacity: 0;
      width: 60px;
    }
    span {
      margin-left: -56px;
    }
    /* 可以根据需要调整操作框的宽高和样式 */
    div {
      cursor: pointer;
      color: #333;
      display: flex;
      align-items: center;
      line-height: 18px;
      font-size: 12px;
      font-weight: bold;
    }

    div + div {
      margin-left: 24px;
    }

    img {
      width: 16px;
      height: 16px;
    }
  }

  .editorTitle {
    width: 100%;
    padding: 24px 24px 16px 24px;
    z-index: 2;
    position: sticky;
    top: 44px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #fff;
    .total {
      color: rgba(0, 1, 27, 0.5);
      font-family: "PingFang SC";
      font-size: 12px;
      font-style: normal;
      font-weight: 400;
      line-height: normal;
    }
    .el-input {
      flex: 1;
    }
    ::v-deep .el-input__inner {
      border: none;
      height: 34px;
      line-height: 34px;
      font-size: 24px;
      color: #00011b;
      font-weight: bold;
      padding-left: 0;
    }
  }

  ::v-deep .w-e-text-placeholder {
    font-style: normal;
  }

  ::v-deep .w-e-bar-item-group .w-e-bar-item-menus-container {
    z-index: 2;
  }
}
</style>
